 package com.guoxue.action.front.pay;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.PathParam;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.guoxue.action.front.BaseAction;
import com.guoxue.domain.BankAuthVo;
import com.guoxue.domain.CoinsVo;
import com.guoxue.domain.RechargeVo;
import com.guoxue.domain.UserCoinsVo;
import com.guoxue.pay.bank.com.cib.epay.sdk.EPay;
import com.guoxue.pay.bank.com.cib.epay.sdk.common.Configure;
import com.guoxue.pay.bank.com.cib.epay.sdk.util.DateTimeUtil;
import com.guoxue.service.IBankAuthService;
import com.guoxue.service.ICoinsService;
import com.guoxue.service.IRechargeService;
import com.guoxue.service.IUserCoinsService;
import com.guoxue.util.JsonUtil;
import com.guoxue.util.OtherUtils;


@Controller
@RequestMapping("/pay")
public class BankPayAction extends BaseAction{
	
	@Resource
	private IRechargeService rechargeService;
	@Resource
	private IUserCoinsService userCoinsService;
	@Resource
	private ICoinsService coinsService;
	@Resource
	private IBankAuthService bankAuthService;

	/**
	 * 银行卡支付
	 * @param req
	 * @param resp
	 * @param coinsId 金币ID
	 * @param count 数量
	 * @param uid 用户id
	 * @param cardNo 银行卡号码
	 * @param acctType 0-储蓄卡;1-信用卡
	 * @param expireDate 过期时间 (信用卡需要)
	 * @param cvn 安全码  (信用卡需要)
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value="/getBankOrderInfo")
	public JSON getBankOrderInfo(HttpServletRequest req, HttpServletResponse resp,
			Integer coinsId, Integer count,Integer uid,String cardNo,String acctType,String expireDate,String cvn){
		try{
			if (coinsId == null) {
				return Message(ERROR, "未提交商品id", null);
			}
			if (count == null) {
				return Message(ERROR, "未提交商品数量", null);
			}
			if(count <= 0){
				return Message(ERROR, "商品数量不能小于等于0", null);
			}
			if(count > 1 ){
				return Message(ERROR, "商品数量超过限制数量", null);
			}
			if (null == uid) {
				return Message(ERROR, "未提交用户id", null);
			}
			if (acctType == "1") {
				if(null == expireDate){
					return Message(ERROR, "未提交信用卡过期时间", null);
				}
				if(null == cvn){
					return Message(ERROR, "未提交信用卡安全码", null);
				}
			}
			
			BankAuthVo bankAuth = bankAuthService.getBankAuth(cardNo,1);
			if( null != bankAuth){
				String ex1_4result = EPay.epAuthQuery(bankAuth.getTracNo());
				Configure.setSub_mrch("博约科技"); // 二级商户名称
				Configure.setMrch_cert(this.getClass().getResource("/").getPath()+"key/Q0000665.pfx");
				Configure.setEpay_cert_prod(this.getClass().getResource("/").getPath()+"key/appsvr_server_prod.crt");
				Configure.setEpay_cert_test(this.getClass().getResource("/").getPath()+"key/appsvr_server_test.crt");
				Configure.setNeedChkSign(false); // 应答是否验签，开发时可以设成false进行调试
				JSONObject jsonObj  = JSONObject.parseObject(ex1_4result);
				String callBack_card_phone = jsonObj.getString("card_phone");
				System.out.println(callBack_card_phone);
				if(null != callBack_card_phone && !"".equals(callBack_card_phone)){
					System.out.println("开始生成订单");
					CoinsVo coinsVo = coinsService.getCoinsById(coinsId);
					if(null == coinsVo){
						return Message(ERROR, "该商品不存在", null);
					}
					Integer price = coinsVo.getPrice();
					RechargeVo recharge = new RechargeVo();
					recharge.setCoinsId(coinsId);
					recharge.setCount(count);
					recharge.setuId(uid);
					int payMoney = count * price;
					recharge.setPayMoney(payMoney);
					recharge.setPayStatus("1");
					recharge.setPayWay("3");
					String aa = OtherUtils.getCurrentDateNum();
				    int bb = (new Random().nextInt(9999-1000+1)+1000);
					String outTradeNo = aa+bb;
					recharge.setOutTradeNo(outTradeNo);
					recharge.setCardNo(cardNo);
					recharge.setCreateTime(OtherUtils.getCurrentDate());
					rechargeService.saveRecharge(recharge);
					String order_amount = payMoney+".00"; // 支付金额
					String order_title = "博约科技SDK支付示例"; // 订单标题
					String order_desc = "10"; // 订单详情
					String ex1_5result = EPay.epPay(outTradeNo, order_amount, order_title, order_desc, cardNo);
					System.out.println(ex1_5result);
					JSONObject jsonObj2  = JSONObject.parseObject(ex1_5result);
					String errmsg = jsonObj2.getString("errmsg");
					String trans_status = jsonObj2.getString("trans_status");
					if(isEmpty(errmsg)){
						String pay_time = jsonObj2.getString("order_time");
						String sno = jsonObj2.getString("sno");
						RechargeVo rechargeCheck = rechargeService.getRecharge(outTradeNo);
						rechargeCheck.setPayStatus("2");
						rechargeCheck.setPresentTime(pay_time);
						rechargeCheck.setTradeNo(sno);
						rechargeService.saveRecharge(rechargeCheck);
						System.out.println("更新订单状态和加入银行卡支付订单号");
						UserCoinsVo userCoinsVo = userCoinsService.getUserCoinsById(recharge.getuId());
						if(null == userCoinsVo){
							userCoinsVo = new UserCoinsVo();
							userCoinsVo.setUid(recharge.getuId());
							CoinsVo coins1 = coinsService.getCoinsById(recharge.getCoinsId());
							System.out.println("BANK增加前金币无记录"+userCoinsVo.getCoinsNumber());
							Integer coinsNumber = coins1.getValue() * recharge.getCount()+coins1.getGiveCoins();
							System.out.println("BANK增加金币无记录"+coinsNumber);
							userCoinsVo.setCoinsNumber(coinsNumber);
							System.out.println("BANK增加后金币无记录"+userCoinsVo.getCoinsNumber());
							userCoinsService.saveUserCoins(userCoinsVo);
						}else{
							CoinsVo coins2 = coinsService.getCoinsById(recharge.getCoinsId());
							System.out.println("BANK增加前金币有记录"+userCoinsVo.getCoinsNumber());
							Integer coinsNumber = coins2.getValue() * recharge.getCount()+coins2.getGiveCoins();
							System.out.println("BANK增加金币有记录"+coinsNumber);
							userCoinsVo.setCoinsNumber(userCoinsVo.getCoinsNumber()+coinsNumber);
							System.out.println("BANK增加后金币有记录"+userCoinsVo.getCoinsNumber());
							userCoinsService.saveUserCoins(userCoinsVo);
						}
						System.out.println("BANK更新用户金币数量");
						return Message(SUCCESS, "支付成功", null);
					}else{
						if(null != errmsg){
							// 两种方式：1、查询当天订单，2、查询指定日期订单
							String ex1_6result = EPay.epQuery(outTradeNo); // order_no为调用EPay.epPay(...)时的订单号
							JSONObject jsonObj3  = JSONObject.parseObject(ex1_6result);
							String errmsg1 = jsonObj3.getString("errmsg");
							if(null == errmsg1){
								String pay_time = jsonObj3.getString("order_time");
								String sno = jsonObj3.getString("sno");
								RechargeVo rechargeCheck = rechargeService.getRecharge(outTradeNo);
								rechargeCheck.setPayStatus("2");
								rechargeCheck.setPresentTime(pay_time);
								rechargeCheck.setTradeNo(sno);
								rechargeService.saveRecharge(rechargeCheck);
								System.out.println("更新订单状态和加入银行卡支付订单号");
								UserCoinsVo userCoinsVo = userCoinsService.getUserCoinsById(recharge.getuId());
								if(null == userCoinsVo){
									userCoinsVo = new UserCoinsVo();
									userCoinsVo.setUid(recharge.getuId());
									CoinsVo coins3 = coinsService.getCoinsById(recharge.getCoinsId());
									System.out.println("BANK增加前金币无记录"+userCoinsVo.getCoinsNumber());
									Integer coinsNumber = coins3.getValue() * recharge.getCount()+coins3.getGiveCoins();
									System.out.println("BANK增加金币无记录"+coinsNumber);
									userCoinsVo.setCoinsNumber(coinsNumber);
									System.out.println("BANK增加后金币无记录"+userCoinsVo.getCoinsNumber());
									userCoinsService.saveUserCoins(userCoinsVo);
								}else{
									CoinsVo coins4 = coinsService.getCoinsById(recharge.getCoinsId());
									System.out.println("BANK增加前金币有记录"+userCoinsVo.getCoinsNumber());
									Integer coinsNumber = coins4.getValue() * recharge.getCount()+coins4.getGiveCoins();
									System.out.println("BANK增加金币有记录"+coinsNumber);
									userCoinsVo.setCoinsNumber(userCoinsVo.getCoinsNumber()+coinsNumber);
									System.out.println("BANK增加后金币有记录"+userCoinsVo.getCoinsNumber());
									userCoinsService.saveUserCoins(userCoinsVo);
								}
								System.out.println("BANK更新用户金币数量");
								return Message(SUCCESS, "支付成功", null);
							}else{
								return Message(ERROR,errmsg1, null);
							}
						}else{
							return Message(ERROR,errmsg, null);
						}
					}
				}else{
					return Message(ERROR, "您还没开通快捷支付功能", "114.55.218.9:8080/pay/authPage.do");
				}
			}else{
				//生成订单相关信息
				CoinsVo coinsVo = coinsService.getCoinsById(coinsId);
				if(null == coinsVo){
					return Message(ERROR, "该商品不存在", null);
				}
				Integer price = coinsVo.getPrice();
				RechargeVo recharge = new RechargeVo();
				recharge.setCoinsId(coinsId);
				recharge.setCount(count);
				recharge.setuId(uid);
				recharge.setPayMoney(count * price);
				recharge.setPayStatus("1");
				recharge.setPayWay("3");
				String aa = OtherUtils.getCurrentDateNum();
			    int bb = (new Random().nextInt(9999-1000+1)+1000);
				String outTradeNo = aa+bb;
				recharge.setOutTradeNo(outTradeNo);
				recharge.setCardNo(cardNo);
				recharge.setCreateTime(OtherUtils.getCurrentDate());
				rechargeService.saveRecharge(recharge);
				return Message(ERROR, "您还没开通快捷支付功能", "114.55.218.9:8080/pay/authPage.do");
			}
		}catch(Exception e){
			return Message(ERROR, "支付失败", null);
		}
	}
	
	@ResponseBody
	@RequestMapping(value="/open")
	public JSON open(HttpServletRequest req, HttpServletResponse resp,
			Integer MessageNumber,String cardNo,String cardPhone,String userName,String acctType,String certNo,String expireDate,String cvn){
		try{
			if(null == MessageNumber){
				if (cardNo == null) {
					return Message(ERROR, "未提交银行卡号", null);
				}
				if (cardPhone == null) {
					return Message(ERROR, "未提交手机号码", null);
				}
				if (userName == null) {
					return Message(ERROR, "未提交姓名", null);
				}
				if (certNo == null) {
					return Message(ERROR, "未提交身份证号码", null);
				}
				if(acctType == "1"){
					if (expireDate == null) {//expireDate (MMYY)
						return Message(ERROR, "未提交信用卡有效期", null);
					}
					if (cvn == null) {
						return Message(ERROR, "未提交信用卡安全码", null);
					}
				}
				String tracNo = "TN"+OtherUtils.getCurrentDateNum();
				String ex1_2aresult = "";
				if(acctType == "0"){
					ex1_2aresult = EPay.epAuthSyncWithSms(tracNo, acctType, null, cardNo, userName, certNo,cardPhone, null, null);
				}else{
					ex1_2aresult = EPay.epAuthSyncWithSms(tracNo, acctType, null, cardNo, userName, certNo,cardPhone, expireDate, cvn);
				}
				JSONObject jsonObj  = JSONObject.parseObject(ex1_2aresult);
				String callBack_card_phone = jsonObj.getString("card_phone");
				String errmsg = jsonObj.getString("errmsg");
				System.out.println(callBack_card_phone);
				if(null != callBack_card_phone && !"".equals(callBack_card_phone)){
					BankAuthVo bankAuth = new BankAuthVo();
					bankAuth.setTracNo(tracNo);
					bankAuth.setCardNo(cardNo);
					bankAuth.setCreateDate(OtherUtils.getCurrentDate());
					bankAuth.setStatus(0);
					bankAuthService.saveBankAuth(bankAuth);
					return Message(SUCCESS, "请输入短信验证码", null);
				}else{
					return Message(ERROR, errmsg, null);
				}
			}else{
				System.out.println("开始支付");
				BankAuthVo bankAuth = bankAuthService.getBankAuth(cardNo,0);
				String ex1_2bresult = EPay.epAuthCheckSms(bankAuth.getTracNo(), MessageNumber.toString());
				JSONObject jsonObj2  = JSONObject.parseObject(ex1_2bresult);
				String auth_status = jsonObj2.getString("auth_status");
				String errmsg2 = jsonObj2.getString("errmsg");
				System.out.println("信息"+errmsg2);
				System.out.println("auth_status"+auth_status);
				if(isEmpty(errmsg2)){
					System.out.println("开始生成订单信息");
					bankAuth.setStatus(1);
					bankAuthService.saveBankAuth(bankAuth);
					RechargeVo recharge = rechargeService.getRechargeCardNo(cardNo,"1");
					System.out.println("recharge"+recharge);
					if(null == recharge){
						return Message(ERROR, "订单创建失败,请重新购买", null);
					}
					int payMoney = recharge.getPayMoney();
					String outTradeNo = recharge.getOutTradeNo();
					String order_amount = payMoney+".00"; // 支付金额
					String order_title = "博约科技SDK支付示例"; // 订单标题
					String order_desc = "10"; // 订单详情
					String ex1_5result = EPay.epPay(outTradeNo, order_amount, order_title, order_desc, cardNo);
					System.out.println(ex1_5result);
					JSONObject jsonObj3  = JSONObject.parseObject(ex1_5result);
					String errmsg = jsonObj3.getString("errmsg");
					if(isEmpty(errmsg)){
						String pay_time = jsonObj3.getString("order_time");
						String sno = jsonObj3.getString("sno");
						RechargeVo rechargeCheck = rechargeService.getRecharge(outTradeNo);
						rechargeCheck.setPayStatus("2");
						rechargeCheck.setPresentTime(pay_time);
						rechargeCheck.setTradeNo(sno);
						rechargeService.saveRecharge(rechargeCheck);
						System.out.println("更新订单状态和加入银行卡支付订单号");
						UserCoinsVo userCoinsVo = userCoinsService.getUserCoinsById(recharge.getuId());
						if(null == userCoinsVo){
							userCoinsVo = new UserCoinsVo();
							userCoinsVo.setUid(recharge.getuId());
							CoinsVo coinsVo = coinsService.getCoinsById(recharge.getCoinsId());
							System.out.println("BANK增加前金币无记录"+userCoinsVo.getCoinsNumber());
							Integer coinsNumber = coinsVo.getValue() * recharge.getCount()+coinsVo.getGiveCoins();
							System.out.println("BANK增加金币无记录"+coinsNumber);
							userCoinsVo.setCoinsNumber(coinsNumber);
							System.out.println("BANK增加后金币无记录"+userCoinsVo.getCoinsNumber());
							userCoinsService.saveUserCoins(userCoinsVo);
						}else{
							CoinsVo coinsVo = coinsService.getCoinsById(recharge.getCoinsId());
							System.out.println("BANK增加前金币有记录"+userCoinsVo.getCoinsNumber());
							Integer coinsNumber = coinsVo.getValue() * recharge.getCount()+coinsVo.getGiveCoins();
							System.out.println("BANK增加金币有记录"+coinsNumber);
							userCoinsVo.setCoinsNumber(userCoinsVo.getCoinsNumber()+coinsNumber);
							System.out.println("BANK增加后金币有记录"+userCoinsVo.getCoinsNumber());
							userCoinsService.saveUserCoins(userCoinsVo);
						}
						System.out.println("BANK更新用户金币数量");
						return Message(SUCCESS, "支付成功", null);
					}else{
						if(null != errmsg){
							// 两种方式：1、查询当天订单，2、查询指定日期订单
							String ex1_6result = EPay.epQuery(outTradeNo); // order_no为调用EPay.epPay(...)时的订单号
							JSONObject jsonObj4  = JSONObject.parseObject(ex1_6result);
							String errmsg1 = jsonObj4.getString("errmsg");
							if(null == errmsg1){
								String pay_time = jsonObj4.getString("order_time");
								String sno = jsonObj4.getString("sno");
								RechargeVo rechargeCheck = rechargeService.getRecharge(outTradeNo);
								rechargeCheck.setPayStatus("2");
								rechargeCheck.setPresentTime(pay_time);
								rechargeCheck.setTradeNo(sno);
								rechargeService.saveRecharge(rechargeCheck);
								System.out.println("更新订单状态和加入银行卡支付订单号");
								UserCoinsVo userCoinsVo = userCoinsService.getUserCoinsById(recharge.getuId());
								if(null == userCoinsVo){
									userCoinsVo = new UserCoinsVo();
									userCoinsVo.setUid(recharge.getuId());
									CoinsVo coinsVo = coinsService.getCoinsById(recharge.getCoinsId());
									System.out.println("BANK增加前金币无记录"+userCoinsVo.getCoinsNumber());
									Integer coinsNumber = coinsVo.getValue() * recharge.getCount();
									System.out.println("BANK增加金币无记录"+coinsNumber);
									userCoinsVo.setCoinsNumber(coinsNumber);
									System.out.println("BANK增加后金币无记录"+userCoinsVo.getCoinsNumber());
									userCoinsService.saveUserCoins(userCoinsVo);
								}else{
									CoinsVo coinsVo = coinsService.getCoinsById(recharge.getCoinsId());
									System.out.println("BANK增加前金币有记录"+userCoinsVo.getCoinsNumber());
									Integer coinsNumber = coinsVo.getValue() * recharge.getCount();
									System.out.println("BANK增加金币有记录"+coinsNumber);
									userCoinsVo.setCoinsNumber(userCoinsVo.getCoinsNumber()+coinsNumber);
									System.out.println("BANK增加后金币有记录"+userCoinsVo.getCoinsNumber());
									userCoinsService.saveUserCoins(userCoinsVo);
								}
								System.out.println("BANK更新用户金币数量");
								return Message(SUCCESS, "支付成功", null);
							}else{
								return Message(ERROR,errmsg1, null);
							}
						}else{
							return Message(ERROR,errmsg, null);
						}
					}
				}else{
					return Message(ERROR, errmsg2, null);
				}
			}
		}catch(Exception e){
			return Message(ERROR, "快捷支付认证开通失败", null);
		}
	}
	
	@ResponseBody
	@RequestMapping(value = "/callBackBankPay")
	public void callBackWXPay(HttpServletRequest req, HttpServletResponse resp) {
			Map<String, String> params = new HashMap<String, String>();
			Map requestParams = req.getParameterMap();
			for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
				String name = (String) iter.next();
				String[] values = (String[]) requestParams.get(name);
				String valueStr = "";
				for (int i = 0; i < values.length; i++) {
					valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
				}
				System.out.println(">>>>>参数" + name + ":" + valueStr);
				params.put(name, valueStr);
			}
			if(!isEmpty(params.get("card_phone"))){
				System.out.println("银行回调"+params.get("card_phone"));
			}else{
				System.out.println("银行回调失败");	
			}
	}
	/**
	 * 跳转支付页面
	 * @param req
	 * @param resp
	 * @param modelMap
	 * @return
	 */
	@RequestMapping("/authPage")
	public ModelAndView view(HttpServletRequest req, HttpServletResponse resp, ModelMap modelMap,
			@RequestParam(value="cardNo",required=true) String cardNo,
			@RequestParam(value="acctType",required=true) String acctType,
			String expireDate,
			String cvn ){
		try{
			modelMap.put("cardNo", cardNo);
			modelMap.put("acctType", acctType);
			modelMap.put("expireDate", expireDate);
			modelMap.put("cvn", cvn);
		}catch(Exception e){
			e.printStackTrace();
		}
		return new ModelAndView("/payment",modelMap);
	}
	
}
